package com.yunji.product.business;

import com.yunji.common.base.BaseBusiness;
import com.yunji.common.enums.common.ErrorEnum;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.product.bo.AttrListQueryBO;
import com.yunji.product.bo.AttrValuesListQueryBO;
import com.yunji.product.bo.ProductAttrsListQueryBO;
import com.yunji.product.domain.AttrDO;
import com.yunji.product.domain.AttrValuesDO;
import com.yunji.product.domain.ProductAttrDO;
import com.yunji.product.dto.AttrDTO;
import com.yunji.product.service.IAttrValuesService;
import com.yunji.product.service.IProductAttrService;
import com.yunji.product.service.IProductAttrsService;
import com.yunji.product.vo.AttrVo;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.product.business
 * @Title: ProductAttrBusiness
 * <p>
 * History:
 * Date                     Version     Author          Summary
 * ============================================================
 * 2024-08-14 10:56:04      V1.0        HuaAo       新建类
 */
@Component
public class ProductAttrBusiness extends BaseBusiness {

    @Resource
    IProductAttrService productAttrService;

    @Resource
    IAttrValuesService attrValuesService;

    @Resource
    IProductAttrsService productAttrsService;

    /**
     * 商品属性列表
     *
     * @param param
     * @return
     */
    public List<AttrVo> search(AttrListQueryBO param) {
        List<AttrVo> voList = new ArrayList<>();
        List<AttrDO> attrList = productAttrService.search(param);

        for (AttrDO attr : attrList) {
            AttrVo vo = new AttrVo();
            Long attrId = attr.getAttrId();
            logs.info("【属性列表】属性ID:{}", attrId);

            AttrValuesListQueryBO attrValues = new AttrValuesListQueryBO();
            attrValues.setAttrId(attrId);
            List<AttrValuesDO> valuesList = attrValuesService.search(attrValues);

            vo.setAttrId(attr.getAttrId());
            vo.setAttrName(attr.getAttrName());
            vo.setSort(attr.getSort());
            vo.setAttrValues(valuesList);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 商品属性详情
     *
     * @param id
     * @return
     */
    public AttrVo select(Long id) {
        AttrListQueryBO param = new AttrListQueryBO();
        param.setAttrId(id);
        List<AttrVo> voList = this.search(param);
        return BeanUtils.isNotNull(voList) ? voList.get(0) : new AttrVo();
    }

    /**
     * @Title 新增商品属性
     * @Desc
     * @Date 2024-08-14 11:39:04.153
     * @Return null
     */
    public Long create(AttrDTO dto) {
        //校验参数
        checkParam(dto);

        //新增商品属性
        AttrDO attr = new AttrDO();
        attr.setAttrName(dto.getAttrName());
        attr.setSort(dto.getSort());
        Assert.isTrue(productAttrService.create(attr), "新增失败");

        //关联商品属性值
        List<AttrValuesDO> list = new ArrayList<>();
        for (AttrValuesDO attrValues : dto.getAttrValues()) {
            attrValues.setAttrId(attr.getAttrId());
            list.add(attrValues);
        }

        for (AttrValuesDO attrValues : list) {
            Assert.isTrue(attrValuesService.create(attrValues), "新增失败");
        }

        return attr.getAttrId();

    }

    /**
     * 修改商品属性
     *
     * @param dto
     */
    @Transactional
    public void update(AttrDTO dto) {
        //校验参数
        checkParam(dto);

        Long attrId = dto.getAttrId();
        logs.info("【修改商品】属性ID:{}", attrId);

        //补充商品属性参数
        AttrDO update = new AttrDO();
        update.setAttrId(dto.getAttrId());
        update.setSort(dto.getSort());
        update.setAttrName(dto.getAttrName());

        //关联商品属性值
        List<AttrValuesDO> newList = new ArrayList<>();
        List<AttrValuesDO> updateList = new ArrayList<>();
        List<Long> updateValues = new ArrayList<>();
        for (AttrValuesDO attrValues : dto.getAttrValues()) {
            attrValues.setAttrId(attrId);
            if (BeanUtils.isNotNull(attrValues.getValueId())) {
                attrValues.setStatus(0);
                updateValues.add(attrValues.getValueId());
                updateList.add(attrValues);
            } else {
                newList.add(attrValues);
            }
        }

        //有使用的则不能删除
        ProductAttrsListQueryBO param = new ProductAttrsListQueryBO();
        param.setAttrId(attrId);
        List<ProductAttrDO> attrList = productAttrsService.search(param);
        List<Long> valueIds = attrList.stream().map(productAttr -> productAttr.getValueId()).collect(Collectors.toList());
        logs.info("【修改属性】被应用属性值ID:{}", valueIds);
        logs.info("【修改属性】修改的属性值ID:{}", updateList);

        for (Long valueId : valueIds) {
            Assert.isTrue(updateValues.contains(valueId), ErrorEnum.BUSINESS_512005.getText());
        }

        //取消所有属性值授权
        AttrValuesDO closeParam = new AttrValuesDO();
        closeParam.setAttrId(attrId);
        closeParam.setStatus(1);
        attrValuesService.update(closeParam);

        //修改商品属性
        Assert.isTrue(productAttrService.update(update), "修改失败");

        //修改属性值关联
        logs.info("【修改属性】修改的属性值信息:{}", updateList);
        for (AttrValuesDO attrValues : updateList) {
            attrValuesService.update(attrValues);
        }

        //重新关联属性值
        logs.info("【修改属性】新增的属性值信息:{}", newList);
        for (AttrValuesDO attrValues : newList) {
            Assert.isTrue(attrValuesService.create(attrValues), "新增失败");
        }
    }

    /**
     * 删除商品属性
     *
     * @param ids
     */
    public void delete(Long... ids) {

        //有商品应用则无法删除
        Assert.isTrue((productAttrsService.statsOfProductAttr(ids) == 0), ErrorEnum.BUSINESS_512004.getText());

        //删除商品属性
        Assert.isTrue(productAttrService.delete(ids), "删除失败");

        //删除商品属性值
        Assert.isTrue(attrValuesService.deleteByAttrIds(ids), "删除失败");
    }


    public Boolean inUse(Long attrId) {
        return (productAttrsService.statsOfProductAttr(attrId) > 0) ? Boolean.TRUE : Boolean.FALSE;
    }

    /*------------------------------------------------校验------------------------------------------------------*/

    private void checkParam(AttrDTO dto) {
        Assert.isTrue(BeanUtils.isNotNull(dto.getAttrName()), "请输入商品属性名");
        Assert.isTrue(BeanUtils.isNotNull(dto.getAttrValues()), "请输入商品属性值");
        Assert.isTrue(BeanUtils.isNotNull(dto.getSort()), "请输入排序序号");

        String attrName = dto.getAttrName();
        List<AttrValuesDO> attrValues = dto.getAttrValues();
        Integer sort = dto.getSort();

        logs.info("【属性校验】商品属性名:{}", attrName);
        logs.info("【属性校验】商品属性值:{}", attrValues);
        logs.info("【属性校验】排序序号:{}", sort);
    }

}